package com.naiterui.ehp.bs.file.controller;

import java.io.File;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.naiterui.ehp.bp.constants.SwaggerTags;
import com.naiterui.ehp.bp.support.utils.FileUtil;
import com.naiterui.ehp.bs.file.api.exception.FileException;
import com.naiterui.ehp.bs.file.api.exception.FileExceptionCodeEnum;
import com.naiterui.ehp.bs.file.domain.FileStore;
import com.naiterui.ehp.bs.file.enums.FileEnum;
import com.naiterui.ehp.bs.file.service.FileService;

import cn.hutool.core.io.file.FileReader;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 文件相关
 *
 * @author yangfuya
 * @since 2021/9/9
 */
@Slf4j
@Api(tags = SwaggerTags.BASE_FILE)
@Validated
@Controller
@RequestMapping
@RequiredArgsConstructor
public class FileController {
    private final FileService fileService;

    @Value("${file.base.prefix}")
    private String fileBasePrefix;

    @ApiOperation("预览")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "uuid", value = "文件唯一标识", required = true, dataType = "string", paramType = "path"),
        @ApiImplicitParam(name = "ec", value = "加密控制字段", required = true, dataType = "string", paramType = "path"),
        @ApiImplicitParam(name = "timestamp", value = "时间戳", required = true, dataType = "string", paramType = "path"),
        @ApiImplicitParam(name = "tc", value = "时间校验", required = true, dataType = "int", paramType = "path"),
        @ApiImplicitParam(name = "sign", value = "链接签名", required = true, dataType = "string", paramType = "path")})
    @GetMapping("/preview/{uuid}/{ec}/{timestamp}/{tc}/{sign}")
    public void preview(@PathVariable("uuid") String uuid, @PathVariable("ec") String ec,
        @PathVariable("timestamp") String timestamp, @PathVariable("tc") Integer tc, @PathVariable("sign") String sign,
        @ApiIgnore HttpServletRequest request, @ApiIgnore HttpServletResponse response) throws FileException {
        FileStore fileStore = fileService.getFileStore(uuid, ec, timestamp, tc, sign, request);
        try {
            FileReader fileReader = new FileReader(fileBasePrefix + fileStore.getUid());
            response.setContentType(FileEnum.getValueByName(fileStore.getSuffix()));
            fileReader.writeToStream(response.getOutputStream());
        } catch (Exception e) {
            log.info("preview io exception: {}", e.getMessage());
            throw new FileException(FileExceptionCodeEnum.FILE_UNAUTHORIZED);
        }
    }

    @ApiOperation("下载")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "uuid", value = "文件唯一标识", required = true, dataType = "string", paramType = "path"),
        @ApiImplicitParam(name = "ec", value = "加密控制字段", required = true, dataType = "string", paramType = "path"),
        @ApiImplicitParam(name = "timestamp", value = "时间戳", required = true, dataType = "string", paramType = "path"),
        @ApiImplicitParam(name = "tc", value = "时间校验", required = true, dataType = "int", paramType = "path"),
        @ApiImplicitParam(name = "sign", value = "链接签名", required = true, dataType = "string", paramType = "path")})
    @GetMapping("/download/{uuid}/{ec}/{timestamp}/{tc}/{sign}")
    public void download(@PathVariable("uuid") String uuid, @PathVariable("ec") String ec,
        @PathVariable("timestamp") String timestamp, @PathVariable("tc") Integer tc, @PathVariable("sign") String sign,
        @ApiIgnore HttpServletRequest request, @ApiIgnore HttpServletResponse response) throws FileException {
        FileStore fileStore = fileService.getFileStore(uuid, ec, timestamp, tc, sign, request);
        FileUtil.downloadFile(request, response, new File(fileBasePrefix + fileStore.getUid()), false);
    }
}